Conversation
- 런타임 에러 Slack 알림과 DEBUG 요청 로그가 같은 요청을 가리키는지 확정할 수 있도록 requestId를 함께 남긴다. - runtime.error 로거가 별도 Slack appender만 사용해 콘솔/파일 로그 패턴의 MDC만으로는 매칭이 어려운 구조를 보완한다. - DEBUG 요청 상세 로그에도 같은 requestId를 포함해 동시 요청 상황에서도 에러와 요청 본문을 구분할 수 있게 한다.
📝 WalkthroughWalkthroughGlobalExceptionHandler가 SLF4J MDC에서 requestId를 추출하여 Slack 에러 알림과 DEBUG 요청 로그에 포함시킵니다. 새로운 Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 60 minutes.Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/gg/agit/konect/global/exception/GlobalExceptionHandler.java (1)
207-213:⚠️ Potential issue | 🔴 Critical[LEVEL: high] 예외 핸들러에서 스택트레이스 첫 요소를 무조건 참조하고 있습니다.
문제: Line 208의e.getStackTrace()[0]는 스택트레이스가 비어있는 예외에서ArrayIndexOutOfBoundsException을 유발할 수 있습니다.
영향: 런타임 예외 처리 중 2차 예외가 발생하면 Slack 알림과 표준 에러 응답 생성이 깨져 장애 분석이 어려워집니다.
제안: 스택트레이스 길이를 검사해 비어있을 때 안전한 기본 location 값을 사용하세요.최소 수정 예시
- StackTraceElement origin = e.getStackTrace()[0]; + StackTraceElement[] stackTrace = e.getStackTrace(); + StackTraceElement origin = stackTrace.length > 0 ? stackTrace[0] : null; @@ - String location = String.format("%s:%d", origin.getFileName(), origin.getLineNumber()); + String location = origin == null + ? "unknown:0" + : String.format("%s:%d", origin.getFileName(), origin.getLineNumber());🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/gg/agit/konect/global/exception/GlobalExceptionHandler.java` around lines 207 - 213, handleException currently does e.getStackTrace()[0] (origin) which throws if the stack trace is empty; change handleException to check e.getStackTrace() length (or null) before indexing and use a safe default location string (e.g., "Unknown:0" or the exception class name) when empty, then build uri, exception, location and message using that safe value so no secondary ArrayIndexOutOfBoundsException occurs during error handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@src/test/java/gg/agit/konect/unit/global/exception/GlobalExceptionHandlerTest.java`:
- Around line 105-106: The test in GlobalExceptionHandlerTest currently checks
.doesNotContain("Body: {\"name\":\"KONECT\"}") which misses the actual log
format that can leak sensitive data; update the assertion on the logger output
(the chain containing .doesNotContain(...)) to either replace or add a check for
.doesNotContain("Body [requestId:") so the test fails if the log contains the
"Body [requestId:"-style payload; locate the assertion in
GlobalExceptionHandlerTest and modify the doesNotContain call(s) accordingly.
---
Outside diff comments:
In `@src/main/java/gg/agit/konect/global/exception/GlobalExceptionHandler.java`:
- Around line 207-213: handleException currently does e.getStackTrace()[0]
(origin) which throws if the stack trace is empty; change handleException to
check e.getStackTrace() length (or null) before indexing and use a safe default
location string (e.g., "Unknown:0" or the exception class name) when empty, then
build uri, exception, location and message using that safe value so no secondary
ArrayIndexOutOfBoundsException occurs during error handling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: e1778ff5-f10e-4c29-85ed-82c98be9199c
📒 Files selected for processing (2)
src/main/java/gg/agit/konect/global/exception/GlobalExceptionHandler.javasrc/test/java/gg/agit/konect/unit/global/exception/GlobalExceptionHandlerTest.java
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: coverage
- GitHub Check: Code Style Check
- GitHub Check: Analyze (java-kotlin)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.java
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.java: Java 코드에서 import로 해결할 수 있는 경우 FQCN(Full Qualified Class Name)을 사용하지 않도록 지적한다
JPA/QueryDSL 조회 변경 시 N+1, 잘못된 fetch join, count 쿼리 왜곡, pagination 깨짐, distinct 누락을 확인한다
권한 로직은 관리자 우회, 요청자와 대상자 관계, 클럽/채팅방/공지/일정의 소속 검증이 빠지지 않았는지 확인한다
soft delete, 탈퇴 사용자, 차단/제외 조건, 중복 제거가 필요한 조회에서는 응답에 노출되면 안 되는 데이터가 포함되는지 확인한다
DTO 응답 변경은 기존 클라이언트가 기대하는 필드명, nullability, enum/string 값, 정렬 순서를 깨지 않는지 확인한다
조건이 2개 이상 결합된 비즈니스 규칙, 권한 조건, soft delete 제외, 중복 제거, fallback 우선순위, 대표값 선택, DTO 변환, count 쿼리 분리, fetch join 선택 이유처럼 코드만으로 의도가 숨겨지는 지점에는 주석을 권장한다
단순 생성자 호출, 필드 매핑, 컬렉션 반환, 이름만으로 명확한 분기에는 주석을 요구하지 않는다
Files:
src/main/java/gg/agit/konect/global/exception/GlobalExceptionHandler.javasrc/test/java/gg/agit/konect/unit/global/exception/GlobalExceptionHandlerTest.java
**/*.{sql,java}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
데이터베이스 변경에서는 마이그레이션 순서, 기존 데이터 호환성, nullable/default 처리, 롤백 난이도, 인덱스 필요성을 확인한다
Files:
src/main/java/gg/agit/konect/global/exception/GlobalExceptionHandler.javasrc/test/java/gg/agit/konect/unit/global/exception/GlobalExceptionHandlerTest.java
src/main/java/**/*.java
⚙️ CodeRabbit configuration file
src/main/java/**/*.java: 아래 원칙으로 리뷰 코멘트를 작성한다.
- 코멘트는 반드시 한국어로 작성한다.
- 반드시 수정이 필요한 항목만 코멘트로 남기고, 단순 취향 차이는 지적하지 않는다.
- 각 코멘트 첫 줄에 심각도를
[LEVEL: high|medium|low]형식으로 반드시 표기한다.- 심각도 기준: high=운영 장애 가능, medium=품질 저하, low=개선 권고.
- 각 코멘트는 "문제 -> 영향 -> 제안" 순서로 3문장 이내로 간결하게 작성한다.
- 가능하면 재현 조건 및 실패 시나리오도 포함한다.
- 제안은 현재 코드베이스(Spring Boot + JPA + Flyway) 패턴과 일치해야 한다.
- 보안, 트랜잭션 경계, 예외 처리, N+1, 성능 회귀 가능성을 우선 점검한다.
- 가독성: 변수/메서드 이름이 의도를 바로 드러내는지, 중첩과 메서드 길이가 과도하지 않은지 점검한다.
- 단순화: 불필요한 추상화, 중복 로직, 과한 방어 코드가 있으면 더 단순한 대안을 제시한다.
- 확장성: 새 요구사항 추가 시 변경 범위가 최소화되는 구조인지(하드코딩 분기/값 여부 포함) 점검한다.
Files:
src/main/java/gg/agit/konect/global/exception/GlobalExceptionHandler.java
**/*
⚙️ CodeRabbit configuration file
**/*: 공통 리뷰 톤 가이드:
- 모든 코멘트는 첫 줄에
[LEVEL: ...]태그를 포함한다.- 과장된 표현 없이 사실 기반으로 작성한다.
- 한 코멘트에는 하나의 이슈만 다룬다.
- 코드 예시가 필요하면 최소 수정 예시를 제시한다.
- 가독성/단순화/확장성 이슈를 발견하면 우선순위를 높여 코멘트한다.
Files:
src/main/java/gg/agit/konect/global/exception/GlobalExceptionHandler.javasrc/test/java/gg/agit/konect/unit/global/exception/GlobalExceptionHandlerTest.java
🧠 Learnings (1)
📚 Learning: 2026-04-25T06:58:54.405Z
Learnt from: CR
Repo: BCSDLab/KONECT_BACK_END PR: 0
File: src/main/java/gg/agit/konect/domain/notification/AGENTS.md:0-0
Timestamp: 2026-04-25T06:58:54.405Z
Learning: Applies to src/main/java/gg/agit/konect/domain/notification/**/*IntegrationTest*.java : Add regression tests for: club application event rollback resulting in zero notifications created (AFTER_COMMIT integration test), inbox list/unread count/bulk read excluding chat-related types (repository integration test), Expo push partial ticket failures logged without whole-request exception propagation, group chat token vs target user count mismatch in current policy.
Applied to files:
src/test/java/gg/agit/konect/unit/global/exception/GlobalExceptionHandlerTest.java
| .doesNotContain("Request [requestId:") | ||
| .doesNotContain("Body: {\"name\":\"KONECT\"}"); |
There was a problem hiding this comment.
[LEVEL: low] DEBUG 비활성화 테스트의 Body 검증 문자열이 현재 포맷과 불일치합니다.
문제: Line 106이 Body: {"name":"KONECT"} 구포맷만 검사해서 Body [requestId: ...] 형태의 본문 로그 누출을 직접 검출하지 못합니다.
영향: DEBUG OFF 회귀가 발생해도 테스트가 통과해 민감 정보 로깅 회귀를 놓칠 수 있습니다.
제안: 현재 포맷 기준으로 doesNotContain("Body [requestId:") 검증을 추가하거나 교체하세요.
최소 수정 예시
assertThat(output)
.doesNotContain("Request [requestId:")
- .doesNotContain("Body: {\"name\":\"KONECT\"}");
+ .doesNotContain("Body [requestId:");🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/test/java/gg/agit/konect/unit/global/exception/GlobalExceptionHandlerTest.java`
around lines 105 - 106, The test in GlobalExceptionHandlerTest currently checks
.doesNotContain("Body: {\"name\":\"KONECT\"}") which misses the actual log
format that can leak sensitive data; update the assertion on the logger output
(the chain containing .doesNotContain(...)) to either replace or add a check for
.doesNotContain("Body [requestId:") so the test fails if the log contains the
"Body [requestId:"-style payload; locate the assertion in
GlobalExceptionHandlerTest and modify the doesNotContain call(s) accordingly.
🧪 JaCoCo Coverage Report (Changed Files)
|
🔍 개요
🚀 주요 변경 내용
runtime.errorSlack 알림 본문에 MDCrequestId를 명시합니다.requestId를 명시합니다.requestId를 공유하는지 테스트로 고정합니다.💬 참고 사항
requestId가 포함되어 있었지만,runtime.error로거는 별도 Slack appender를 사용하고additivity=false라 Slack 알림 자체에는 식별자가 남지 않았습니다.CI=true ./gradlew test --tests 'gg.agit.konect.unit.global.exception.GlobalExceptionHandlerTest' --rerun-tasks,CI=true ./gradlew checkstyleMain✅ Checklist (완료 조건)